package dao

import (
	"context"
	"mini-app/internal/define"
	"mini-app/internal/models"

	"192.168.1.75/go-pkg/errorx"
	"gorm.io/gorm"
)

type GoodsReview struct{}

// 新增评测
func (GoodsReview) Create(
	ctx context.Context,
	db *gorm.DB,
	record models.GoodsReview,
) (id string, err error) {
	rowsAffected := db.WithContext(ctx).Model(&models.GoodsReview{}).Create(&record).RowsAffected
	if rowsAffected <= 0 {
		return "", errorx.New("评测失败", -1)
	}
	return record.ID, nil
}

// 更新评测
func (GoodsReview) Update(
	ctx context.Context,
	db *gorm.DB,
	openid string,
	id string,
	star string,
	content string,
	images string,
) bool {
	// 构建更新字段的 map
	updateFields := make(map[string]interface{})

	// content 总是更新
	updateFields["content"] = content

	// images 总是更新（即使为空）
	updateFields["images"] = images

	// star 只有在不为空时才更新
	updateFields["star"] = star

	rowsAffected := db.WithContext(ctx).
		Model(&models.GoodsReview{}).
		Where("id = ?", id).
		Updates(updateFields).RowsAffected
	return rowsAffected == 1
}

// ResetAuditStatus 评测修改->重置审核状态
func (GoodsReview) ResetAuditStatus(
	ctx context.Context,
	db *gorm.DB,
	id string,
) {
	db.WithContext(ctx).Model(&models.GoodsReview{}).
		Where("id = ?", id).
		Updates(map[string]interface{}{
			"audit_id": nil,
		})
}

func (GoodsReview) Detail(
	ctx context.Context,
	db *gorm.DB,
	id string,
) *GoodsReviewListT {
	var record GoodsReviewListT
	tx := db.WithContext(ctx).Model(&models.Order{}).
		Joins("join goods_review on order.review_id = goods_review.id").
		Joins("left join goods_review_audit_log on goods_review.audit_id = goods_review_audit_log.id")
	tx = tx.Where("goods_review.id = ?", id)
	rowsAffected := tx.Select([]string{
		"order.id as order_id",
		"order.goods_id",
		"goods_review.id",
		"goods_review.openid",
		"goods_review.star",
		"goods_review.content",
		"goods_review.images",
		"goods_review.created_at",
		"goods_review.visible",
		"goods_review_audit_log.id as audit_id",
		"goods_review_audit_log.audit_status",
		"goods_review_audit_log.reason",
	}).Take(&record).RowsAffected

	if rowsAffected <= 0 {
		return nil
	}
	return &record
}

// Delete 删除评测
func (GoodsReview) Delete(
	ctx context.Context,
	db *gorm.DB,
	id string,
) bool {
	rowsAffected := db.WithContext(ctx).Model(&models.GoodsReview{}).
		Where("id = ?", id).
		Delete(&models.GoodsReview{}).
		RowsAffected
	return rowsAffected == 1
}

type GoodsReviewListT struct {
	ID           string `json:"id" gorm:"column:id"`                                 // 评测id
	OrderID      string `json:"order_id,omitempty" gorm:"column:order_id"`           // 订单id
	GoodsID      string `json:"goods_id,omitempty" gorm:"column:goods_id"`           // 商品id
	GoodsType    int    `json:"goods_type,omitempty" gorm:"-"`                       // 商品类型
	GoodsName    string `json:"goods_name,omitempty" gorm:"column:goods_name"`       // 商品名称
	GoodsImage   string `json:"goods_image,omitempty"`                               // 商品图片
	ReviewPoints int    `json:"review_points" gorm:"-"`                              // 评测可获得的积分
	OpenID       string `json:"-" gorm:"column:openid"`                              // openid
	WechatName   string `json:"wechat_name" gorm:"-"`                                // 微信名称
	WeChatAvatar string `json:"wechat_avatar,omitempty" gorm:"-"`                    // 微信头像
	Star         string `json:"star" gorm:"column:star"`                             // 星级
	Content      string `json:"content" gorm:"column:content"`                       // 评价内容
	Images       string `json:"images" gorm:"column:images"`                         // 评测的图片
	AuditID      string `json:"audit_id" gorm:"column:audit_id"`                     // 审核id
	AuditStatus  int    `json:"audit_status" gorm:"column:audit_status"`             // 审核状态
	AuditUserID  string `json:"audit_user_id,omitempty" gorm:"column:audit_user_id"` // 审核人id
	AuditUser    string `json:"audit_user,omitempty" gorm:"-"`                       // 审核人
	AuditTime    int64  `json:"audit_time,omitempty" gorm:"column:audit_time"`       // 审核时间
	Reason       string `json:"reason" gorm:"column:reason"`                         // 拒绝原因
	Visible      int    `json:"visible" gorm:"column:visible"`                       // 是否对外显示
	CreatedAt    int64  `json:"created_at" gorm:"column:created_at"`                 // 创建时间
}

// List 评测列表
func (GoodsReview) List(
	ctx context.Context,
	db *gorm.DB,
	openID string,
	goodsID string,
	goodsType int,
	goodsName string,
	visible int,
	auditStatus int,        // 0-待审核 1-审核通过 2-审核未通过
	status int,             // 0-全部 1-已评测 2-待评测
	startTime, endTime int, // 开始时间-结束时间
	page, limit int,
) (records []GoodsReviewListT, total int64) {
	var fields = []string{}
	tx := db.WithContext(ctx).Model(&models.Order{})
	if status == 1 {
		tx = tx.Joins("join goods_review on order.review_id = goods_review.id")
		if auditStatus == -1 {
			tx = tx.Joins("left join goods_review_audit_log on goods_review.audit_id = goods_review_audit_log.id")
		} else if auditStatus == 0 {
			tx = tx.Where("goods_review.audit_id IS NULL")
			tx = tx.Joins("left join goods_review_audit_log on goods_review.audit_id = goods_review_audit_log.id")
		} else {
			tx = tx.Joins("join goods_review_audit_log on goods_review.audit_id = goods_review_audit_log.id")
			tx = tx.Where("goods_review_audit_log.audit_status = ?", auditStatus)
		}
	} else {
		tx = tx.Joins("left join goods_review on order.review_id = goods_review.id").
			Joins("left join goods_review_audit_log on goods_review.audit_id = goods_review_audit_log.id")
	}
	if startTime > 0 && endTime > 0 {
		tx = tx.Where("goods_review.created_at BETWEEN ? AND ?", startTime, endTime)
	}
	if openID != "" {
		tx = tx.Where("order.openid = ?", openID)
	}
	if status == 1 { // 已评测
		tx = tx.Where("order.review_id IS NOT NULL")
	}
	if status == 2 { // 待评测
		tx = tx.Where("order.review_id IS NULL AND order.order_status = ?", define.OrderStatusPendingReview)
	}
	if goodsID != "" {
		tx = tx.Where("order.goods_id = ?", goodsID)
	}
	if goodsType > 0 {
		tx = tx.Where("order.goods_type = ?", goodsType)
	}
	if goodsName != "" {
		tx = tx.Where("order.goods_name LIKE ?", "%"+goodsName+"%")
	}
	if visible > 0 {
		tx = tx.Where("goods_review.visible = ?", visible)
	}
	tx.Count(&total)
	if limit > 0 {
		if limit > 2000 {
			limit = 2000
		}
		tx = tx.Limit(limit)
	}
	if page > 0 && limit > 0 {
		tx = tx.Offset((page - 1) * limit)
	}
	fields = append(fields, []string{
		"order.id as order_id",
		"order.goods_id",
		"goods_review.id",
		"goods_review.openid",
		"goods_review.star",
		"goods_review.content",
		"goods_review.images",
		"goods_review.created_at",
		"goods_review.visible",
		"goods_review_audit_log.id as audit_id",
		"goods_review_audit_log.audit_status",
		"goods_review_audit_log.reason",
	}...)
	tx = tx.Select(fields)
	if status == 1 {
		tx = tx.Order("goods_review.created_at desc")
	} else {
		tx = tx.Order("order.created_at desc")
	}
	tx.Find(&records)
	return
}

// Audit 评测审核
func (GoodsReview) Audit(
	ctx context.Context,
	db *gorm.DB,
	id string,
	auditStatus int,    // 0-待审核 1-审核通过 2-审核不通过
	reason string,      // 拒绝通过的原因
	visible int,        // 是否显示，审核通过默认显示
	auditUserID string, // 审核人
) bool {
	if auditStatus == 1 {
		reason = ""
	}
	var record = models.GoodsReviewAuditLog{
		ReviewID:    id,
		AuditStatus: auditStatus,
		Reason:      reason,
		AuditUserID: auditUserID,
	}
	// 增加一条审核记录
	db.WithContext(ctx).Model(&models.GoodsReviewAuditLog{}).Create(&record)
	// 评测记录关联审核记录
	rowsAffected := db.WithContext(ctx).Model(&models.GoodsReview{}).
		Where("id = ?", id).
		Updates(&models.GoodsReview{
			Visible: visible,
			AuditID: record.ID,
		}).RowsAffected
	return rowsAffected == 1
}

func (GoodsReview) GetAuditStatus(
	ctx context.Context,
	db *gorm.DB,
	auditID string,
) *models.GoodsReviewAuditLog {
	var record models.GoodsReviewAuditLog
	rowsAffected := db.WithContext(ctx).
		Where("id = ?", auditID).
		Take(&record).RowsAffected
	if rowsAffected <= 0 {
		return nil
	}
	return &record
}

// SetVisible 设置评测是否展示
func (GoodsReview) SetVisible(
	ctx context.Context,
	db *gorm.DB,
	reviewIDs []string,
	visible int,
) bool {
	rowsAffected := db.WithContext(ctx).Model(&models.GoodsReview{}).
		Where("id IN ?", reviewIDs).
		Update("visible", visible).
		RowsAffected
	return rowsAffected > 0
}

// AuditLog 审核日志
func (GoodsReview) AuditLog(
	ctx context.Context,
	db *gorm.DB,
	goodsType int,          // 商品类型
	goodsName string,       // 商品名称
	auditStatus int,        // 审核状态，1-审核通过 2-审核未通过
	startTime, endTime int, // 开始时间-结束时间
	page, limit int,        // 分页
) (records []GoodsReviewListT, total int64) {
	tx := db.WithContext(ctx).Model(&models.GoodsReviewAuditLog{}).
		Joins("join goods_review on goods_review.id = goods_review_audit_log.review_id").
		Joins("join `order` on `order`.review_id = goods_review.id")

	if auditStatus > 0 {
		tx = tx.Where("goods_review_audit_log.audit_status = ?", auditStatus)
	}

	if startTime > 0 && endTime > 0 {
		tx = tx.Where("goods_review_audit_log.created_at BETWEEN ? AND ?", startTime, endTime)
	}
	if goodsType > 0 {
		tx = tx.Where("order.goods_type = ?", goodsType)
	}
	if goodsName != "" {
		tx = tx.Where("order.goods_name LIKE ?", "%"+goodsName+"%")
	}
	tx.Count(&total)
	if limit > 0 {
		if limit > 2000 {
			limit = 2000
		}
		tx = tx.Limit(limit)
	}
	if page > 0 && limit > 0 {
		tx = tx.Offset((page - 1) * limit)
	}
	tx.Select([]string{
		"order.id as order_id",
		"order.goods_id",
		"goods_review.id",
		"goods_review.openid",
		"goods_review.star",
		"goods_review.content",
		"goods_review.images",
		"goods_review.created_at",
		"goods_review.visible",
		"goods_review_audit_log.id as audit_id",
		"goods_review_audit_log.audit_status",
		"goods_review_audit_log.reason",
		"goods_review_audit_log.audit_user_id",
		"goods_review_audit_log.created_at as audit_time",
	}).Order("goods_review_audit_log.created_at desc").Find(&records)
	return
}
